package com.dc.juc.example._10_aqs;

import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;


/**
 * Description: CyclicBarrier 循环屏障
 *  会让所有线程都等待完成后才会继续下一步行动
 *
 *      CyclicBarrier(int parties, Runnable barrierAction)：
 *          创建一个新的 CyclicBarrier，它将在给定数量的参与者（线程）处于等待状态时启动，并在启动 barrier 时执行给定的屏障操作，该操作由最后一个进入 barrier 的线程执行
 *
 *  执行的现象：每一秒打印一次ready，累计5次后，先打印callback is running，接着再同时打印5次continue；然后循环当前
 *
 * @author: gdc
 * @date: 2021/8/16
 * @version 1.0
 */
@Slf4j
public class CyclicBarrier3 {

    private static CyclicBarrier cyclicBarrier = new CyclicBarrier(5,
            () -> log.info("callback is running"));

    @SneakyThrows
    public static void main(String[] args){

        ExecutorService threadPool = Executors.newCachedThreadPool();

        for (int i = 0; i < 10; i++) {
            TimeUnit.SECONDS.sleep(1);
            threadPool.execute(() -> {
                race(Thread.currentThread().getId());
            });
        }

        threadPool.shutdown();

    }

    @SneakyThrows
    private static void race(long threadNum) {
        TimeUnit.SECONDS.sleep(1);
        log.info("{} is ready", threadNum);

        cyclicBarrier.await();

        log.info("{} continue", threadNum);
    }
}